//leancloud 请求统一调用此方法函数，请问独立请求。
let AV = require('leancloud-storage');
const gap = 10;
const AND = 'and';
const OR = 'or';
let LeanCloudUtils = {};
/**
 * 全部查询以及模糊查询  当option.searchFilter为undefined时 查询全部 每次查询10项
 * 默认条件之间都为且关系
 * @param option
 *  option.table 表名
 * option.page 当前页码
 * option.logic 条件之间的关系  且为'and' 或为 'or'默认为'and' searchFilter exceptFilter 等等的过滤器也一样
 * option.searchFilter 筛选条件
 * option.exceptFilter 不包含的条件
 * option.gap 每页条数
 * @param callback
 * @param failure
 */
LeanCloudUtils.queryTable = function (option, callback, failure) {
  let table = option.table;
  let page = option.page;
  let searchFilter = option.searchFilter ? option.searchFilter.filter : undefined;
  let exceptFilter = option.exceptFilter ? option.exceptFilter.filter : undefined;
  let equalFilter = option.equalFilter ? option.equalFilter.filter : undefined;
  let notEqualFilter = option.notEqualFilter ? option.notEqualFilter.filter : undefined;
  let include = option.include;
  let query;
  let searchFilters;
  let exceptFilters;
  let equalFilters;
  let notEqualFilters;
  if (searchFilter) {
    searchFilters = [];
    for (let i = 0; i < searchFilter.length; i++) {
      Object.keys(searchFilter[i]).forEach(function (key) {
        let query = new AV.Query(table);
        query.contains(key, searchFilter[i][key]);
        searchFilters.push(query);
      })
    }
  }

  if (exceptFilter) {
    exceptFilters = [];
    for (let i = 0; i < exceptFilter.length; i++) {
      Object.keys(exceptFilter[i]).forEach(function (key) {
        let query = new AV.Query(table);
        query.notEqualTo(key, exceptFilter[i][key]);
        exceptFilters.push(query);
      })
    }
    console.log(exceptFilters);
    if (query) {
      query.and(...exceptFilters);
    }
    else {
      query = AV.Query.and(...exceptFilters)
    }
  }

  if (equalFilter) {
    equalFilters = [];
    for (let i = 0; i < equalFilter.length; i++) {
      Object.keys(equalFilter[i]).forEach(function (key) {
        let query = new AV.Query(table);
        query.equalTo(key, equalFilter[i][key]);
        equalFilters.push(query);
      })
    }
  }


  if (notEqualFilter) {
    notEqualFilters = [];
    for (let i = 0; i < notEqualFilter.length; i++) {
      Object.keys(notEqualFilter[i]).forEach(function (key) {
        let query = new AV.Query(table);
        query.equalTo(key, notEqualFilter[i][key]);
        notEqualFilters.push(query);
      })
    }
  }

  let allFilters = [];
  if (searchFilters) {
    if (option.searchFilter.logic === undefined || option.searchFilter.logic === AND) {
      allFilters.push(AV.Query.and(...searchFilters));
    }
    else {
      allFilters.push(AV.Query.or(...searchFilters));
    }
  }
  if (exceptFilters) {
    if (option.exceptFilter.logic === undefined || option.exceptFilter.logic === AND) {
      allFilters.push(AV.Query.and(...exceptFilters));
    }
    else {
      allFilters.push(AV.Query.or(...exceptFilters));
    }
  }
  if (equalFilters) {
    if (option.equalFilter.logic === undefined || option.equalFilter.logic === AND) {
      allFilters.push(AV.Query.and(...equalFilters));
    }
    else {
      allFilters.push(AV.Query.or(...equalFilters));
    }
  }
  if (notEqualFilters) {
    if (option.notEqualFilter.logic === undefined || option.notEqualFilter.logic === AND) {
      allFilters.push(AV.Query.and(...notEqualFilters));
    }
    else {
      allFilters.push(AV.Query.or(...notEqualFilters));
    }
  }
  if(allFilters.length) {
    if (option.logic === undefined || option.logic === AND) {
      query = AV.Query.and(...allFilters);
    }
    else {
      query = AV.Query.or(...allFilters);
    }
  }
  else{
    query = new AV.Query(table);
  }
  if(include){
    query.include(include);
  }
  query.limit(gap);
  query.skip(gap * (page - 1));
  if (page === 1) {
    query.count().then(function (count) {
      query.find().then(function (res) {
        console.log(res);
        callback(res, count);
      }, function (error) {
        console.log(error);
        if (failure !== undefined) {
          failure(error);
        }
      }).catch(function (e) {
        console.log(e);
        if (failure !== undefined) {
          failure(e);
        }
      })
    });
  }
  else {
    query.find().then(function (res) {
      callback(res);
    }, function (error) {
      console.log(error);
      if (failure !== undefined) {
        failure(error);
      }
    }).catch(function (e) {
      console.log(e);
      if (failure !== undefined) {
        failure(e);
      }
    })
  }
};

/**
 * 查询表 没有限制数量
 * @param option
 * @param callback
 * @param failure
 */
LeanCloudUtils.queryNoLimit = function (option, callback, failure) {
  let table = option.table;
  let page = option.page;
  let searchFilter = option.searchFilter ? option.searchFilter.filter : undefined;
  let exceptFilter = option.exceptFilter ? option.exceptFilter.filter : undefined;
  let equalFilter = option.equalFilter ? option.equalFilter.filter : undefined;
  let notEqualFilter = option.notEqualFilter ? option.notEqualFilter.filter : undefined;
  let include = option.include;
  let query;
  let searchFilters;
  let exceptFilters;
  let equalFilters;
  let notEqualFilters;
  if (searchFilter) {
    searchFilters = [];
    for (let i = 0; i < searchFilter.length; i++) {
      Object.keys(searchFilter[i]).forEach(function (key) {
        let query = new AV.Query(table);
        query.contains(key, searchFilter[i][key]);
        searchFilters.push(query);
      })
    }
  }

  if (exceptFilter) {
    exceptFilters = [];
    for (let i = 0; i < exceptFilter.length; i++) {
      Object.keys(exceptFilter[i]).forEach(function (key) {
        let query = new AV.Query(table);
        query.notEqualTo(key, exceptFilter[i][key]);
        exceptFilters.push(query);
      })
    }
    console.log(exceptFilters);
    if (query) {
      query.and(...exceptFilters);
    }
    else {
      query = AV.Query.and(...exceptFilters)
    }
  }

  if (equalFilter) {
    equalFilters = [];
    for (let i = 0; i < equalFilter.length; i++) {
      Object.keys(equalFilter[i]).forEach(function (key) {
        let query = new AV.Query(table);
        query.equalTo(key, equalFilter[i][key]);
        equalFilters.push(query);
      })
    }
  }


  if (notEqualFilter) {
    notEqualFilters = [];
    for (let i = 0; i < notEqualFilter.length; i++) {
      Object.keys(notEqualFilter[i]).forEach(function (key) {
        let query = new AV.Query(table);
        query.equalTo(key, notEqualFilter[i][key]);
        notEqualFilters.push(query);
      })
    }
  }

  let allFilters = [];
  if (searchFilters) {
    if (option.searchFilter.logic === undefined || option.searchFilter.logic === AND) {
      allFilters.push(AV.Query.and(...searchFilters));
    }
    else {
      allFilters.push(AV.Query.or(...searchFilters));
    }
  }
  if (exceptFilters) {
    if (option.exceptFilter.logic === undefined || option.exceptFilter.logic === AND) {
      allFilters.push(AV.Query.and(...exceptFilters));
    }
    else {
      allFilters.push(AV.Query.or(...exceptFilters));
    }
  }
  if (equalFilters) {
    if (option.equalFilter.logic === undefined || option.equalFilter.logic === AND) {
      allFilters.push(AV.Query.and(...equalFilters));
    }
    else {
      allFilters.push(AV.Query.or(...equalFilters));
    }
  }
  if (notEqualFilters) {
    if (option.notEqualFilter.logic === undefined || option.notEqualFilter.logic === AND) {
      allFilters.push(AV.Query.and(...notEqualFilters));
    }
    else {
      allFilters.push(AV.Query.or(...notEqualFilters));
    }
  }
  if(allFilters.length) {
    if (option.logic === undefined || option.logic === AND) {
      query = AV.Query.and(...allFilters);
    }
    else {
      query = AV.Query.or(...allFilters);
    }
  }
  else{
    query = new AV.Query(table);
  }
  if(include){
    query.include(include);
  }
  query.limit(1000);
  if (page === 1) {
    query.count().then(function (count) {
      query.find().then(function (res) {
        console.log(res);
        callback(res, count);
      }, function (error) {
        console.log(error);
        if (failure !== undefined) {
          failure(error);
        }
      }).catch(function (e) {
        console.log(e);
        if (failure !== undefined) {
          failure(e);
        }
      })
    });
  }
  else {
    query.find().then(function (res) {
      callback(res);
    }, function (error) {
      console.log(error);
      if (failure !== undefined) {
        failure(error);
      }
    }).catch(function (e) {
      console.log(e);
      if (failure !== undefined) {
        failure(e);
      }
    })
  }
};

/**
 * 修改数据
 * @param option
 * option.table 需要修改的表
 * option.file 需要修改的文件
 * option.editData 修改修改的参数
 * option.objectId 需要修改的item的objectid
 * @param callback
 * @param failure
 */
LeanCloudUtils.editTableObject = function (option, callback, failure) {
  let table = option.table;
  let editData = option.editData;
  let objectId = option.objectId;
  let file = option.file;

  if (file === undefined) {
    let todo = AV.Object.createWithoutData(table, objectId);
    for (let i = 0; i < editData.length; i++) {
      Object.keys(editData[i]).forEach(function (key) {
        todo.set(key, editData[i][key]);
      });
    }
    todo.save().then(function (res) {
      console.log(res);
      callback(res);
    }, function (e) {
      console.log(e);
      if (failure !== undefined) {
        failure(e);
      }
    }).catch(function (e) {
      console.log(e);
      if (failure !== undefined) {
        failure(e);
      }
    });
  }
  else {
    let saveFile = new AV.File(file.name, file);
    saveFile.save().then(function (res) {
      let todo = AV.Object.createWithoutData(table, objectId);
      for (let i = 0; i < editData.length; i++) {
        Object.keys(editData[i]).forEach(function (key) {
          todo.set(key, editData[i][key]);
        });
      }
      todo.set('url', res.attributes.url);
      todo.save().then(function (res) {
        console.log(res);
        callback(res);
      }, function (e) {
        console.log(e);
        if (failure !== undefined) {
          failure(e);
        }
      }).catch(function (e) {
        console.log(e);
        if (failure !== undefined) {
          failure(e);
        }
      });
    });
  }

};

/**
 * 添加数据
 * @param option
 * option.addData 为需要添加的数据
 * option.file 需要上传的文件
 * option.table 需要
 * @param callback
 * @param failure
 *
 */
LeanCloudUtils.addTableObject = function (option, callback, failure) {
  let table = option.table;
  let addData = option.addData;
  let file = option.file;
  let TableObject = AV.Object.extend(table);
  let tableObject = new TableObject();
  //当包含了文件
  if (file !== undefined) {
    let saveFile = new AV.File(file.name, file);
    saveFile.save().then(function (res) {
      tableObject.set('url', res.attributes.url);
      for (let i = 0; i < addData.length; i++) {
        Object.keys(addData[i]).forEach(function (key) {
          tableObject.set(key, addData[i][key]);
        });
      }
      tableObject.save().then(function (res) {
        console.log(res);
        callback(res);
      }, function (error) {
        console.log(error);
        if (failure !== undefined) {
          failure(error)
        }
      });
    }).catch(function (error) {
      console.log(error)
    })
  }
  //不包含文件
  else {
    for (let i = 0; i < addData.length; i++) {
      Object.keys(addData[i]).forEach(function (key) {
        tableObject.set(key, addData[i][key]);
      })
    }
    tableObject.save().then(function (res) {
      console.log(res);
      callback(res);
    }, function (error) {
      console.log(error);
      if (failure !== undefined) {
        failure(error)
      }
    });
  }
};

/**
 * 删除数据　
 * @param option
 * option.table 表
 * option.objectId  要删除数据的objectId
 * @param callback
 * @param failure
 */
LeanCloudUtils.deleteData = function (option, callback, failure) {
  let table = option.table;
  let objectId = option.objectId;
  let todo = AV.Object.createWithoutData(table, objectId);
  todo.destroy().then(function (success) {
    console.log(success);
    callback(success);
  }, function (error) {
    if (failure !== undefined) {
      failure(error);
    }
  }).catch(function (e) {
    if (failure !== undefined) {
      failure(error);
    }
  });
};


LeanCloudUtils.logOut = function () {
  AV.User.logOut();
};
module.exports  = LeanCloudUtils;
